package com.cjkj.common.core.utils;

import com.cjkj.common.core.domain.runset.*;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class RunModeSetUtil {

    private RunModeSetUtil(){}

    public static RunSetParam getSetInfo(SendCommandReq req){
        Date visitTime = req.getVisitTime();
        String mode = req.getMode();

        RunSetParam runSet = new RunSetParam();
        runSet.setMode(mode);

        RunSetParamDetails ecgParamDetails = new RunSetParamDetails();
        if("1".equals(mode) || "3".equals(mode)) {
            // 1-两个计划，2-五个计划
            String bpPlan = req.getBpPlan();
            TimeSetDto bpPlanDaytime = req.getBpPlanDaytime();
            TimeSetDto bpPlanNight = req.getBpPlanNight();

            // 白天开始时间
            int dayStart = Integer.parseInt(StringUtils.isNotBlank(bpPlanDaytime.getStart()) ? bpPlanDaytime.getStart().substring(0, 2) : "08");
            // 白天结束时间
            int dayEnd = Integer.parseInt(StringUtils.isNotBlank(bpPlanDaytime.getEnd()) ? bpPlanDaytime.getEnd().substring(0, 2) : "20");
            // 夜间开始时间
            int nightStart = Integer.parseInt(StringUtils.isNotBlank(bpPlanNight.getStart()) ? bpPlanNight.getStart().substring(0, 2) : "20");
            // 夜间结束时间
            int nightEnd = Integer.parseInt(StringUtils.isNotBlank(bpPlanNight.getEnd()) ? bpPlanNight.getEnd().substring(0, 2) : "08");

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(visitTime);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            List<RunSetParamDetailsTimeValue> bpTimes = new ArrayList<>();
            if("1".equals(bpPlan)) {
                // 如果在白天时段内开单的
                int visitHour = calendar.get(Calendar.HOUR_OF_DAY);
                if(visitHour >= dayStart && visitHour <= dayEnd) {
                    // 第一个时段（白天）
                    calendar.set(Calendar.HOUR_OF_DAY, dayStart);
                    Date dayStartTimeOne = calendar.getTime();
                    calendar.set(Calendar.HOUR_OF_DAY, dayEnd);
                    Date dayEndTimeOne = setEndTimes(calendar.getTime());

                    // 第二个时段（夜晚）
                    calendar.set(Calendar.HOUR_OF_DAY, nightStart);
                    if (nightStart < dayEnd) {
                        calendar.add(Calendar.DAY_OF_MONTH, 1);
                    }
                    Date nightStartTimeOne = calendar.getTime();
                    calendar.set(Calendar.HOUR_OF_DAY, nightEnd);
                    if(nightEnd < nightStart) {
                        calendar.add(Calendar.DAY_OF_MONTH, 1);
                    }
                    Date nightEndTimeOne = setEndTimes(calendar.getTime());

                    bpTimes.add(new RunSetParamDetailsTimeValue("1", dayStartTimeOne.getTime(), dayEndTimeOne.getTime(), bpPlanDaytime.getReminder(), bpPlanDaytime.getInterval()));
                    bpTimes.add(new RunSetParamDetailsTimeValue("2", nightStartTimeOne.getTime(), nightEndTimeOne.getTime(), bpPlanNight.getReminder(), bpPlanNight.getInterval()));

                }
                // 如果在夜晚时段内开单的
                else {
                    // 第一个时段（夜晚）
                    calendar.set(Calendar.HOUR_OF_DAY, nightStart);
                    Date nightStartTimeOne = calendar.getTime();
                    calendar.set(Calendar.HOUR_OF_DAY, nightEnd);
                    if(nightEnd == 0 || nightEnd < nightStart) {
                        calendar.add(Calendar.DAY_OF_MONTH, 1);
                    }
                    Date nightEndTimeOne = setEndTimes(calendar.getTime());
                    if(nightEnd == 0 || nightEnd < nightStart) {
                        calendar.add(Calendar.DAY_OF_MONTH, -1);
                    }

                    // 第二个时段（白天）
                    calendar.set(Calendar.HOUR_OF_DAY, dayStart);
                    if (dayStart < nightEnd || nightEnd == 0 || nightEnd < nightStart) {
                        calendar.add(Calendar.DAY_OF_MONTH, 1);
                    }
                    Date dayStartTimeOne = calendar.getTime();
                    calendar.set(Calendar.HOUR_OF_DAY, dayEnd);
                    Date dayEndTimeOne = setEndTimes(calendar.getTime());

                    bpTimes.add(new RunSetParamDetailsTimeValue("2", nightStartTimeOne.getTime(), nightEndTimeOne.getTime(), bpPlanNight.getReminder(), bpPlanNight.getInterval()));
                    bpTimes.add(new RunSetParamDetailsTimeValue("1", dayStartTimeOne.getTime(), dayEndTimeOne.getTime(), bpPlanDaytime.getReminder(), bpPlanDaytime.getInterval()));
                }
            } else if("2".equals(bpPlan)) {
                // 如果在白天时段内开单的
                int visitHour = calendar.get(Calendar.HOUR_OF_DAY);
                if(visitHour >= dayStart && visitHour <= dayEnd) {
                    // 第一个时段（白天）
                    calendar.set(Calendar.HOUR_OF_DAY, dayStart);
                    Date dayStartTimeOne = calendar.getTime();
                    calendar.set(Calendar.HOUR_OF_DAY, dayEnd);
                    Date dayEndTimeOne = setEndTimes(calendar.getTime());

                    // 第二个时段（夜晚）
                    calendar.set(Calendar.HOUR_OF_DAY, nightStart);
                    if (nightStart < dayEnd) {
                        calendar.add(Calendar.DAY_OF_MONTH, 1);
                    }
                    Date nightStartTimeOne = calendar.getTime();
                    calendar.set(Calendar.HOUR_OF_DAY, nightEnd);
                    if(nightEnd < nightStart) {
                        calendar.add(Calendar.DAY_OF_MONTH, 1);
                    }
                    Date nightEndTimeOne = setEndTimes(calendar.getTime());

                    bpTimes.add(new RunSetParamDetailsTimeValue("1", dayStartTimeOne.getTime(), dayEndTimeOne.getTime(), bpPlanDaytime.getReminder(), bpPlanDaytime.getInterval()));
                    bpTimes.add(new RunSetParamDetailsTimeValue("2", nightStartTimeOne.getTime(), nightEndTimeOne.getTime(), bpPlanNight.getReminder(), bpPlanNight.getInterval()));

                    Date dayStartTimeTwo = addOneDay(dayStartTimeOne);
                    Date dayEndTimeTwo = setEndTimes(addOneDay(dayEndTimeOne));
                    bpTimes.add(new RunSetParamDetailsTimeValue("1", dayStartTimeTwo.getTime(), dayEndTimeTwo.getTime(), bpPlanDaytime.getReminder(), bpPlanDaytime.getInterval()));

                    Date nightStartTimeTwo = addOneDay(nightStartTimeOne);
                    Date nightEndTimeTwo = setEndTimes(addOneDay(nightEndTimeOne));
                    bpTimes.add(new RunSetParamDetailsTimeValue("2", nightStartTimeTwo.getTime(), nightEndTimeTwo.getTime(), bpPlanNight.getReminder(), bpPlanNight.getInterval()));

                    Date dayStartTimeThree = addOneDay(dayStartTimeTwo);
                    Date dayEndTimeThree = setEndTimes(addOneDay(dayEndTimeTwo));
                    bpTimes.add(new RunSetParamDetailsTimeValue("1", dayStartTimeThree.getTime(), dayEndTimeThree.getTime(), bpPlanDaytime.getReminder(), bpPlanDaytime.getInterval()));
                }
                // 如果在夜晚时段内开单的
                else {
                    // 第一个时段（夜晚）
                    calendar.set(Calendar.HOUR_OF_DAY, nightStart);
                    Date nightStartTimeOne = calendar.getTime();
                    calendar.set(Calendar.HOUR_OF_DAY, nightEnd);
                    if(nightEnd == 0 || nightEnd < nightStart) {
                        calendar.add(Calendar.DAY_OF_MONTH, 1);
                    }
                    Date nightEndTimeOne = setEndTimes(calendar.getTime());
                    if(nightEnd == 0 || nightEnd < nightStart) {
                        calendar.add(Calendar.DAY_OF_MONTH, -1);
                    }

                    // 第二个时段（白天）
                    calendar.set(Calendar.HOUR_OF_DAY, dayStart);
                    if (dayStart < nightEnd || nightEnd == 0 || nightEnd < nightStart) {
                        calendar.add(Calendar.DAY_OF_MONTH, 1);
                    }
                    Date dayStartTimeOne = calendar.getTime();
                    calendar.set(Calendar.HOUR_OF_DAY, dayEnd);
                    Date dayEndTimeOne = setEndTimes(calendar.getTime());

                    bpTimes.add(new RunSetParamDetailsTimeValue("2", nightStartTimeOne.getTime(), nightEndTimeOne.getTime(), bpPlanNight.getReminder(), bpPlanNight.getInterval()));
                    bpTimes.add(new RunSetParamDetailsTimeValue("1", dayStartTimeOne.getTime(), dayEndTimeOne.getTime(), bpPlanDaytime.getReminder(), bpPlanDaytime.getInterval()));

                    Date nightStartTimeTwo = addOneDay(nightStartTimeOne);
                    Date nightEndTimeTwo = setEndTimes(addOneDay(nightEndTimeOne));
                    bpTimes.add(new RunSetParamDetailsTimeValue("2", nightStartTimeTwo.getTime(), nightEndTimeTwo.getTime(), bpPlanNight.getReminder(), bpPlanNight.getInterval()));

                    Date dayStartTimeTwo = addOneDay(dayStartTimeOne);
                    Date dayEndTimeTwo = setEndTimes(addOneDay(dayEndTimeOne));
                    bpTimes.add(new RunSetParamDetailsTimeValue("1", dayStartTimeTwo.getTime(), dayEndTimeTwo.getTime(), bpPlanDaytime.getReminder(), bpPlanDaytime.getInterval()));

                    Date nightStartTimeThree = addOneDay(nightStartTimeTwo);
                    Date nightEndTimeThree = setEndTimes(addOneDay(nightEndTimeTwo));
                    bpTimes.add(new RunSetParamDetailsTimeValue("2", nightStartTimeThree.getTime(), nightEndTimeThree.getTime(), bpPlanNight.getReminder(), bpPlanNight.getInterval()));
                }
            }

            ecgParamDetails.setBpPlan(bpPlan);
            ecgParamDetails.setBpTimes(bpTimes);
        }

        if("2".equals(mode) || "3".equals(mode)) {
            // 动态心电
            TimeSetDto ecgTime = req.getEcgTime();
            int ecgStart = Integer.parseInt(StringUtils.isNotBlank(ecgTime.getStart()) ? ecgTime.getStart().substring(0, 2) : "00");
            int ecgEnd = Integer.parseInt(StringUtils.isNotBlank(ecgTime.getEnd()) ? ecgTime.getEnd().substring(0, 2) : "23");

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(visitTime);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            int visitHour = calendar.get(Calendar.HOUR_OF_DAY);
            if (visitHour <= ecgStart) {
                // 如果开单时间的小时数小于等于动态心电开始小时数，那么就从动态心电开始时间开始
                calendar.set(Calendar.HOUR_OF_DAY, ecgStart);
                Date ecgStartTime = calendar.getTime();

                calendar.set(Calendar.HOUR_OF_DAY, ecgEnd);
                Date ecgEndTime = setEndTimes(calendar.getTime());
                if(ecgStart > ecgEnd) {
                    // 如果动态心电开始小时数大于结束小时数，那么可能是跨天
                    ecgEndTime = setEndTimes(addOneDay(ecgEndTime));
                }
                RunSetParamDetailsTimeValue ecgTimes = new RunSetParamDetailsTimeValue(ecgStartTime.getTime(), ecgEndTime.getTime());
                ecgParamDetails.setEcgTimes(ecgTimes);
            } else {
                // 如果开单时间的小时数大于动态心电开始小时数，那么时间设置为第二天开始
                calendar.set(Calendar.HOUR_OF_DAY, ecgStart);
                calendar.add(Calendar.DAY_OF_MONTH, 1);
                Date ecgStartTime = calendar.getTime();
                calendar.set(Calendar.HOUR_OF_DAY, ecgEnd);
                Date ecgEndTime = setEndTimes(calendar.getTime());
                if(ecgStart >= ecgEnd) {
                    ecgEndTime = setEndTimes(addOneDay(ecgEndTime));
                }
                RunSetParamDetailsTimeValue ecgTimes = new RunSetParamDetailsTimeValue(ecgStartTime.getTime(), ecgEndTime.getTime());
                ecgParamDetails.setEcgTimes(ecgTimes);
            }
        }
        runSet.setSet(ecgParamDetails);

        return runSet;
    }

    private static Date addOneDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        return calendar.getTime();
    }

    private static Date setEndTimes(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 获取动态血压、动态心电设置中最晚的结束时间
     * @param runSetParam
     */
    public static Long getTheLatestTime(RunSetParam runSetParam) {
        Long timeMills = 0L;
        if(runSetParam != null) {
            RunSetParamDetails set = runSetParam.getSet();
            if(set != null) {
                // 动态心电监测时间段
                RunSetParamDetailsTimeValue ecgTimes = set.getEcgTimes();
                if (ecgTimes != null) {
                    timeMills = ecgTimes.getEnd();
                }

                // 动态血压监测时间段
                List<RunSetParamDetailsTimeValue> bpTimes = set.getBpTimes();
                if (bpTimes != null && !bpTimes.isEmpty()) {
                    for (RunSetParamDetailsTimeValue bpTime : bpTimes) {
                        if (timeMills < bpTime.getEnd()) {
                            timeMills = bpTime.getEnd();
                        }
                    }
                }
            }
        }

        return timeMills;
    }

}
